"""
Tests for the update() queryset method that allows in-place, multi-object
updates.
"""

from django.db import models

#
# Model for testing arithmetic expressions.
#

class Number(models.Model):
    integer = models.IntegerField()
    float = models.FloatField(null=True)

    def __unicode__(self):
        return u'%i, %.3f' % (self.integer, self.float)

#
# A more ordinary use case.
#

class Employee(models.Model):
    firstname = models.CharField(max_length=50)
    lastname = models.CharField(max_length=50)

    def __unicode__(self):
        return u'%s %s' % (self.firstname, self.lastname)

class Company(models.Model):
    name = models.CharField(max_length=100)
    num_employees = models.PositiveIntegerField()
    num_chairs = models.PositiveIntegerField()
    ceo = models.ForeignKey(
        Employee,
        related_name='company_ceo_set')
    point_of_contact = models.ForeignKey(
        Employee,
        related_name='company_point_of_contact_set',
        null=True)

    def __unicode__(self):
        return self.name


__test__ = {'API_TESTS': """
>>> from django.db.models import F

>>> Number(integer=-1).save()
>>> Number(integer=42).save()
>>> Number(integer=1337).save()

We can fill a value in all objects with an other value of the same object.

>>> Number.objects.update(float=F('integer'))
>>> Number.objects.all()
[<Number: -1, -1.000>, <Number: 42, 42.000>, <Number: 1337, 1337.000>]

We can increment a value of all objects in a query set.

>>> Number.objects.filter(integer__gt=0).update(integer=F('integer') + 1)
>>> Number.objects.all()
[<Number: -1, -1.000>, <Number: 43, 42.000>, <Number: 1338, 1337.000>]

We can filter for objects, where a value is not equals the value of an other field.

>>> Number.objects.exclude(float=F('integer'))
[<Number: 43, 42.000>, <Number: 1338, 1337.000>]

Complex expressions of different connection types are possible.

>>> n = Number.objects.create(integer=10, float=123.45)
>>> Number.objects.filter(pk=n.pk).update(float=F('integer') + F('float') * 2)
>>> Number.objects.get(pk=n.pk)
<Number: 10, 256.900>

All supported operators, work as expected in native and reverse order.

>>> from operator import add, sub, mul, div, mod, and_, or_
>>> for op in (add, sub, mul, div, mod, and_, or_):
...     n = Number.objects.create(integer=42, float=15.)
...     Number.objects.filter(pk=n.pk).update(
...         integer=op(F('integer'), 15), float=op(42., F('float')))
...     Number.objects.get(pk=n.pk)
<Number: 57, 57.000>
<Number: 27, 27.000>
<Number: 630, 630.000>
<Number: 3, 2.800>
<Number: 12, 12.000>
<Number: 10, 10.000>
<Number: 47, 47.000>


>>> Company(name='Example Inc.', num_employees=2300, num_chairs=5,
...     ceo=Employee.objects.create(firstname='Joe', lastname='Smith')).save()
>>> Company(name='Foobar Ltd.', num_employees=3, num_chairs=3,
...     ceo=Employee.objects.create(firstname='Frank', lastname='Meyer')).save()
>>> Company(name='Test GmbH', num_employees=32, num_chairs=1,
...     ceo=Employee.objects.create(firstname='Max', lastname='Mustermann')).save()

We can filter for companies where the number of employees is greater than the
number of chairs.

>>> Company.objects.filter(num_employees__gt=F('num_chairs'))
[<Company: Example Inc.>, <Company: Test GmbH>]

The relation of a foreign key can become copied over to an other foreign key.

>>> Company.objects.update(point_of_contact=F('ceo'))
>>> [c.point_of_contact for c in Company.objects.all()]
[<Employee: Joe Smith>, <Employee: Frank Meyer>, <Employee: Max Mustermann>]

"""}
